package com.lz.app.demo.interceptor;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.lz.app.demo.annotations.TokenRequired;
import com.lz.app.demo.jwt.Jwt;
import com.lz.app.demo.jwt.TokenState;
import lombok.extern.slf4j.Slf4j;

import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * @Title: SecurityInterceptor
 * @ProjectName app-service
 * @Author huchao
 * @Date 2018/9/5上午9:23
 */
@Slf4j
public class SecurityInterceptor implements HandlerInterceptor {
	@Override
	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
		String url = httpServletRequest.getRequestURI();
		Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
		Map<String, String> headerMap = new HashMap<>();
		while (headerNames.hasMoreElements()) {
			String name = headerNames.nextElement();
			String value = httpServletRequest.getHeader(name);
			headerMap.put(name, value);
		}
		log.info("SecurityInterceptor preHandler url:" + url
				+ " header:" + JSONObject.toJSONString(headerMap)
				+ " params:" + JSONObject.toJSONString(httpServletRequest.getParameterMap())
				+ " method:" + httpServletRequest.getMethod());
		if (hasPermission(httpServletRequest, o)) {
			return true;
		}

		httpServletResponse.sendError(HttpStatus.FORBIDDEN.value(), "无权限");
		return false;
	}

	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

	}

	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

	}

	private boolean hasPermission(HttpServletRequest httpServletRequest, Object handler) {
		String token = httpServletRequest.getHeader("token");
		if (handler instanceof HandlerMethod) {
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			// 获取方法上的注解
			TokenRequired tokenRequired = handlerMethod.getMethod().getAnnotation(TokenRequired.class);
			// 如果方法上的注解为空 则获取类的注解
			if (tokenRequired == null) {
				tokenRequired = handlerMethod.getMethod().getDeclaringClass().getAnnotation(TokenRequired.class);
			}
			// 如果标记了注解，则判断权限
			if (tokenRequired != null) {
				if (StringUtils.isEmpty(token)) {
					return false;
				} else {
					JSONObject jsonObject = validJWT(token);
					if (jsonObject == null) {
						return false;
					} else {
						Integer userId = jsonObject.getInteger("id");
						if (userId != null) {
							httpServletRequest.setAttribute("userId", userId);
							return true;
						} else {
							return false;
						}
					}
				}
			}
		}
		return true;
	}

	private JSONObject validJWT(String token) {
		try {
			Map<String, Object> resultMap = Jwt.validToken(token);
			TokenState state = TokenState.getTokenState((String) resultMap.get("state"));
			switch (state) {
				case VALID:
					String str = (String) resultMap.get("data");
					JSONObject jsonObject = JSONObject.parseObject(str);
					return jsonObject;
				case EXPIRED:
				case INVALID:
				default:
					return null;
			}
		} catch (Exception e) {
			log.info(e.getMessage());
			return null;
		}
	}
}
